package bman.game.engine;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.util.Enumeration;
import java.util.Properties;
import java.util.logging.Logger;

public class Entity
{
	Logger log = Logger.getLogger(this.getClass().getName());
	
	public static final String ID = "ID";
	public static final String X = "X";
	public static final String Y = "Y";
	public static final String Z = "Z";
	public static final String BEARING = "BEARING";
	public static final String TYPE = "TYPE";
	public static final String MOVABLE = "MOVABLE";
	public static final String ACTIVE = "ACTIVE";
	public static final String LIFE = "LIFE";
	
	private int m_x;
	private int m_y;
	private int z;
	
	private int width;
	private int height;
	private int life = 100;
	
	private boolean movable = true;
	private boolean active = true;
		
	private String m_type;
	private String id = "-1";
	
	private String bearing = "";
	
	private Properties props = new Properties();
	
	protected Entity(String id, String type, int x, int y, int z)
	{
		this.id = id;
		setType(type);
		updatePosition(x,y);
		z(z);
		width = ImageLibrary.getImage(type+bearing).getWidth(null);
		height = ImageLibrary.getImage(type).getHeight(null);
	}
	
	public String toString()
	{
		return
			ID+":"+getID()+","+
			X+":"+x()+","+
			Y+":"+y()+","+
			Z+":"+z()+","+
			BEARING+":"+getBearing()+","+
			TYPE+":"+getType()+","+
			MOVABLE+":"+movable()+","+
			LIFE+":"+life()
			;
	}
	
	public int life()
	{
		return life;
	}
	
	public void life(int life)
	{
		this.life = life;
		this.recordChanges(LIFE, life);
	}
	
	public String id()
	{
		return id;
	}
	
	public int z()
	{
		return z;
	}
	
	public void z(int z)
	{
		this.z = z;
		recordChanges("Z", z);
	}
	
	public void setType(String s)
	{
		this.m_type = s;
		recordChanges("TYPE", m_type);
	}
	
	public boolean hasChanges()
	{
		return !props.isEmpty();
	}
	
	/**
	 * Returns the changes to this Entities attributes since the last time this method was called.
	 * The format of the changes is "ID:xxx,<field1>:<value>,<field2>:<value>,<fieldn>:<value>"
	 */
	public String getChanges()
	{
		StringBuffer sb = new StringBuffer(ID+":"+getID()+",");
		
		Enumeration e =  props.keys();
		while(e.hasMoreElements())
		{
			String key = (String)e.nextElement();
			sb.append(key+":"+props.get(key)+",");
		}
		
		props.clear();
		return sb.toString();
	}
	
	private void recordChanges(String fieldName, int value)
	{
		recordChanges(fieldName, String.valueOf(value));
	}
	
	private void recordChanges(String fieldName, String value)
	{
		props.put(fieldName,value);
		log.finest("Entity has changed: "+props);
	}
	
	public void movable(boolean movable)
	{
		this.movable = movable;
		recordChanges("MOVABLE","FALSE");
	}
	
	public boolean movable()
	{
		return movable;
	}
	
	public void width(int width)
	{
		this.width = width;
	}
	
	public void height(int height)
	{
		this.height = height;
	}
	
	public int width()
	{
		return width;
	}
	
	public int height()
	{
		return height;
	}
	
	public void updatePosition(int x, int y)
	{
		this.m_x = x;
		this.m_y = y;
		recordChanges("X",m_x);
		recordChanges("Y",m_y);
	}
	
	public void x(int x)
	{
		updatePosition(x,m_y);
	}
	
	public void y(int y)
	{
		updatePosition(m_x,y);
	}
	
	public int x()
	{
		return m_x;
	}
	
	public int y()
	{
		return m_y;
	}
	
	public void deactivate()
	{
		isActive(false);
	}
	
	public boolean isActive()
	{
		return active;
	}
	
	public void isActive(boolean b)
	{
		active = b;
		recordChanges("ACTIVE",Boolean.toString(active));

	}
	
	public String getBearing()
	{
		return bearing;
	}
	
	public void setBearing(String bearing)
	{
		this.bearing = bearing;
		recordChanges("BEARING",bearing);
	}
	
	public String getID()
	{
		return id;
	}
	
	public void setID(String id)
	{
		this.id = id;		
	}
	
	public String getType()
	{
		return m_type;
	}
	
	public Shape getShape()
	{
		return new Rectangle(m_x,m_y,width,height);
	}
}

